#! user/bin/python
# -*- coding: utf-8 -*-

"""
Created on 2021/8/19 11:36

@File: 派生服务器_multi-server.py
@Author: LT
@Description: Use of this module
"""
import os, time, sys
from socket import *
from multiprocessing import Process

myHost = ""
myPort = 50007

# sockobj = socket(AF_INET, SOCK_STREAM)
# sockobj.bind((myHost, myPort))
# sockobj.listen(5)


def now():
    return time.ctime(time.time())


activeChildren = []


def reapChildren():                                     # 收割所有的僵尸子进程
    while activeChildren:                               # 不然可能它们会塞满系统任务栏
        pid, stat = os.waitpid(0, os.WNOHANG)           # 子进程退出时候不挂起
        if not pid:
            break
        activeChildren.remove(pid)


def handleClient(connection):
    print("Child:", os.getpid())
    time.sleep(5)
    while True:
        data = connection.recv(1024)
        if not data:
            break
        reply = "Echo=>%s at %s" % (data, now())
        connection.send(reply.encode())
    connection.close()
    sys.exit(0)                                         # os._exit(0)用不了，先用这个代替


def dispatcher():
    """持续监听，等待客户端连接进来，知道进程被终止"""
    while True:
        connection, address = sockobj.accept()
        print("Server connected by", address, end="")
        print("at", now())
        Process(target=handleClient, args=(connection,)).start()
        # reapChildren()
        # childPid = os.fork()
        # if childPid == 0:                               # 如果在子进程中：则调用handle
        #     handleClient(connection)
        # else:                                           # 否则：去accept接受下一个连接
        #     activeChildren.append(childPid)             # 将该childPid添加金活跃的子进程pid列表


if __name__ == '__main__':
    print("Parent:", os.getpid())
    sockobj = socket(AF_INET, SOCK_STREAM)
    sockobj.bind((myHost, myPort))
    sockobj.listen(5)
    dispatcher()
